package com.code.wflow.handler;

import com.code.wflow.constants.InstanceNodeStage;
import com.code.wflow.constants.NodeTypeEnum;
import com.code.wflow.constants.TaskStatusEnum;
import com.code.wflow.model.InstanceNode;
import com.code.wflow.model.InstanceNodeDetail;
import com.code.wflow.model.WorkflowNode;
import com.code.wflow.model.WorkflowTask;
import com.code.wflow.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 流程执行器
 *
 * @author ggh
 * @date 2022/11/24
 */
@Component
public class InstanceActuator {

    @Autowired
    private InstanceService instanceService;

    @Autowired
    private InstanceNodeService instanceNodeService;

    @Autowired
    private InstanceNodeDetailService instanceNodeDetailService;

    @Autowired
    private WorkflowNodeService nodeService;

    @Autowired
    private WorkflowTaskService taskService;

    /**
     * 执行下一步
     *
     * @param instanceId 流程实例id
     * @return
     */
    public boolean performNextInstance(Long instanceId, Integer prevLevel, Integer conditionLevel) {
        Integer level = prevLevel + 1;
        InstanceNode nextInstanceNode = null;

        List<InstanceNode> addInstanceNodeList = new ArrayList<>();
        if (conditionLevel == null) {
            nextInstanceNode = instanceNodeService.queryNodeByLevel(instanceId, level);
        } else {
            InstanceNode prevInstanceNode = instanceNodeService.queryNodeByLevel(instanceId, prevLevel);
            //条件节点已结束，查询下一个节点
            if (prevInstanceNode.getEnd()) {
                nextInstanceNode = instanceNodeService.queryNodeByLevel(instanceId, prevInstanceNode.getConditionsLevel() + 1);
            } else {
                WorkflowNode workflowNode = nodeService.queryNodeByCondition(prevInstanceNode.getWorkflowId(), prevInstanceNode.getCode());
                nextInstanceNode = copyWorkflowNode(workflowNode, instanceId);

                addInstanceNodeList.add(nextInstanceNode);
            }
        }


        List<InstanceNode> updateInstanceNodeList = new ArrayList<>();
        List<WorkflowTask> taskList = new ArrayList<>();

        // 循环获取流程下一个节点，根据节点类型添加响应的任务，直到到流程末尾或者审批节点
        while (nextInstanceNode != null) {
            WorkflowNode nextNode = nodeService.queryById(nextInstanceNode.getWorkflowNodeId());
            if (NodeTypeEnum.START.getType().equals(nextNode.getType())) {
                nextInstanceNode.setStage(InstanceNodeStage.END.getVal());
                updateInstanceNodeList.add(nextInstanceNode);
            } else if (NodeTypeEnum.CC.getType().equals(nextNode.getType())) {
                nextInstanceNode.setStage(InstanceNodeStage.END.getVal());
                updateInstanceNodeList.add(nextInstanceNode);

                List<InstanceNodeDetail> detailList = instanceNodeDetailService.queryByInstanceNode(nextInstanceNode.getId());
                for (InstanceNodeDetail detail : detailList) {
                    WorkflowTask tempTask = new WorkflowTask();
                    tempTask.setInstanceId(detail.getInstanceId());
                    tempTask.setInstanceNodeDetailId(detail.getId());
                    tempTask.setExecutorId(detail.getExecutorId());
                    tempTask.setExecutorName(detail.getExecutorName());
                    tempTask.setStatus(TaskStatusEnum.UNREAD.getVal());
                    taskList.add(tempTask);
                }
            } else if (NodeTypeEnum.APPROVAL.getType().equals(nextNode.getType())) {
                List<InstanceNodeDetail> detailList = instanceNodeDetailService.queryByInstanceNode(nextInstanceNode.getId());

                nextInstanceNode.setStage(InstanceNodeStage.PROGRESSING.getVal());
                updateInstanceNodeList.add(nextInstanceNode);
                for (InstanceNodeDetail detail : detailList) {
                    WorkflowTask tempTask = new WorkflowTask();
                    tempTask.setInstanceId(detail.getInstanceId());
                    tempTask.setInstanceNodeDetailId(detail.getId());
                    tempTask.setExecutorId(detail.getExecutorId());
                    tempTask.setExecutorName(detail.getExecutorName());
                    tempTask.setStatus(TaskStatusEnum.TODO.getVal());
                    taskList.add(tempTask);
                }

                break;
            } else if (NodeTypeEnum.CONIDITIONS.getType().equals(nextNode.getType())) {
                List<InstanceNodeDetail> detailList = instanceNodeDetailService.queryByInstanceNode(nextInstanceNode.getId());

                nextInstanceNode.setStage(InstanceNodeStage.PROGRESSING.getVal());
                updateInstanceNodeList.add(nextInstanceNode);
                for (InstanceNodeDetail detail : detailList) {
                    WorkflowTask tempTask = new WorkflowTask();
                    tempTask.setInstanceId(detail.getInstanceId());
                    tempTask.setInstanceNodeDetailId(detail.getId());
                    tempTask.setExecutorId(detail.getExecutorId());
                    tempTask.setExecutorName(detail.getExecutorName());
                    tempTask.setStatus(TaskStatusEnum.TODO.getVal());
                    taskList.add(tempTask);
                }

                break;
            }

            nextInstanceNode = instanceNodeService.queryNodeByLevel(instanceId, level + 1);
        }

        // 更新节点数据并判断流程是否结束
        if (instanceService.performInstance(instanceId, taskList, updateInstanceNodeList, nextInstanceNode == null)) {
            return true;
        }

        return false;
    }

    /**
     * 执行下一步
     *
     * @param instanceId 流程实例id
     * @return
     */
    public boolean performNextInstanceOld(Long instanceId, Integer level) {
        // todo 查询下一个节点的方式需要修改
        InstanceNode nextInstanceNode = instanceNodeService.queryNodeByLevel(instanceId, level);
        if (nextInstanceNode == null) {
            return true;
        }

        List<InstanceNode> updateInstanceNodeList = new ArrayList<>();
        List<WorkflowTask> taskList = new ArrayList<>();

        // 循环获取流程下一个节点，根据节点类型添加响应的任务，直到到流程末尾或者审批节点
        while (nextInstanceNode != null) {
            WorkflowNode nextNode = nodeService.queryById(nextInstanceNode.getWorkflowNodeId());
            if (NodeTypeEnum.START.getType().equals(nextNode.getType())) {
                nextInstanceNode.setStage(InstanceNodeStage.END.getVal());
                updateInstanceNodeList.add(nextInstanceNode);
            } else if (NodeTypeEnum.CC.getType().equals(nextNode.getType())) {
                nextInstanceNode.setStage(InstanceNodeStage.END.getVal());
                updateInstanceNodeList.add(nextInstanceNode);

                List<InstanceNodeDetail> detailList = instanceNodeDetailService.queryByInstanceNode(nextInstanceNode.getId());
                for (InstanceNodeDetail detail : detailList) {
                    WorkflowTask tempTask = new WorkflowTask();
                    tempTask.setInstanceId(detail.getInstanceId());
                    tempTask.setInstanceNodeDetailId(detail.getId());
                    tempTask.setExecutorId(detail.getExecutorId());
                    tempTask.setExecutorName(detail.getExecutorName());
                    tempTask.setStatus(TaskStatusEnum.UNREAD.getVal());
                    taskList.add(tempTask);
                }
            } else if (NodeTypeEnum.APPROVAL.getType().equals(nextNode.getType())) {
                List<InstanceNodeDetail> detailList = instanceNodeDetailService.queryByInstanceNode(nextInstanceNode.getId());

                nextInstanceNode.setStage(InstanceNodeStage.PROGRESSING.getVal());
                updateInstanceNodeList.add(nextInstanceNode);
                for (InstanceNodeDetail detail : detailList) {
                    WorkflowTask tempTask = new WorkflowTask();
                    tempTask.setInstanceId(detail.getInstanceId());
                    tempTask.setInstanceNodeDetailId(detail.getId());
                    tempTask.setExecutorId(detail.getExecutorId());
                    tempTask.setExecutorName(detail.getExecutorName());
                    tempTask.setStatus(TaskStatusEnum.TODO.getVal());
                    taskList.add(tempTask);
                }

                break;
            }

            nextInstanceNode = instanceNodeService.queryNodeByLevel(instanceId, level + 1);
        }

        // 更新节点数据并判断流程是否结束
        if (instanceService.performInstance(instanceId, taskList, updateInstanceNodeList, nextInstanceNode == null)) {
            return true;
        }

        return false;
    }

    private InstanceNode copyWorkflowNode(WorkflowNode workflowNode, Long instanceId) {
        InstanceNode instanceNode = new InstanceNode();
        instanceNode.setWorkflowId(workflowNode.getWorkflowId());
        instanceNode.setInstanceId(instanceId);
        instanceNode.setWorkflowNodeId(workflowNode.getId());
        instanceNode.setStartTime(new Date());
        instanceNode.setLevel(workflowNode.getLevel());
        instanceNode.setConditionsLevel(workflowNode.getConditionsLevel());
        instanceNode.setStage(InstanceNodeStage.PROGRESSING.getVal());
        instanceNode.setCode(workflowNode.getCode());
        return instanceNode;
    }
}
